home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 June / MacFormat 25.iso / Shareware City / Developers / GlueWindow4.1(source) Folder / Source(THINK C7.0) / GlueWindowCDEV4.1.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-01-04  |  17.8 KB  |  684 lines  |  [TEXT/KAHL]

  1. //    GlueWindowCDEV4.1.c
  2.  
  3. //    inclusion of files -----------------------------
  4.  
  5. #include    <OSUtils.h>
  6. #include    "GlueWindow4.1.h"
  7.  
  8. //    definition -------------------------------------
  9.  
  10. enum    {    k_about    =    1,
  11.             k_drag_on,
  12.             k_grow_on,
  13.             k_push_on,
  14.             k_push_sound,
  15.             k_push_ctrl,
  16.             k_push_shift,
  17.             k_push_option,
  18.             k_push_command,
  19.             b_push_ctrl,
  20.             b_push_shift,
  21.             b_push_option,
  22.             b_push_command,
  23.             k_pop_on,
  24.             k_pop_sound,
  25.             k_pop_ctrl,
  26.             k_pop_shift,
  27.             k_pop_option,
  28.             k_pop_command,
  29.             b_pop_ctrl,
  30.             b_pop_shift,
  31.             b_pop_option,
  32.             b_pop_command,
  33.             k_show_icon,
  34.             k_no_marquee,
  35.             k_drag_ctrl,
  36.             k_drag_shift,
  37.             k_drag_option,
  38.             k_drag_command,
  39.             b_drag_ctrl,
  40.             b_drag_shift,
  41.             b_drag_option,
  42.             b_drag_command    };
  43.             
  44. #define        ALERT_RSRC        0
  45. #define        ABOUT_RSRC        1
  46. #define        RESTART_RSRC    2
  47. #define        SAME_RSRC        3
  48. #define        COMMAND_RSRC    4
  49. #define        NO_7_RSRC        5
  50. #define        WINDOW_ICON        2
  51. #define        key1            (**ch).temp_init_data.push_key
  52. #define        key2            (**ch).temp_init_data.pop_key
  53. #define        key3            (**ch).temp_init_data.drag_key
  54.  
  55. //    declaration of prototypes ----------------------
  56.  
  57. pascal long    main(short msg, short item, short numItems,
  58.                     short panelId, EventRecord *evntp, long val,
  59.                         DialogPtr dp);
  60. Boolean    is_system7(void);
  61. Handle    Get1Resource_in_system_heap(OSType rType, short id);
  62.                     
  63. short        NumToolboxTraps( void );
  64. TrapType    GetTrapType(short theTrap);
  65. Boolean        TrapAvailable(short theTrap);
  66.  
  67. long            do_check(DialogPtr dp);
  68. long            do_init    (DialogPtr dp, short numItems);
  69. init_data_hdl    load_setting(void);
  70. int                open_prefs_file(prefs_file *pf);
  71. void            save_setting(init_data_hdl save_data_hdl, prefs_file *pf_ptr);
  72. void            do_close(cdev_data_hdl ch);
  73.  
  74. void do_hit            (cdev_data_hdl ch, DialogPtr dp, short hit_item,
  75.                                 EventRecord *evntp, short numItems);
  76. void apply_setting    (cdev_data_hdl cur_data_hdl);
  77. void setup_ditems    (cdev_data_hdl ch, DialogPtr dp, short numItems);
  78. void hilite_btn        (cdev_data_hdl ch, DialogPtr dp, short numItems);
  79. void set_check_btn    (DialogPtr dp, short item_num, Boolean check);
  80. void check_key_combination(cdev_data_hdl ch, short key_num);
  81. void about(short id, void *p);
  82.  
  83. //    main routines ----------------------------------
  84.  
  85. pascal long main(short msg, short item, short numItems, short panelId,
  86.                     EventRecord *evntp, long val, DialogPtr dp)
  87. {
  88.     long    rv;
  89.     
  90.     rv = val;
  91.     switch(msg) {
  92.         case nulDev:
  93.         case activDev:
  94.         case deactivDev:
  95.         case keyEvtDev:
  96.         case undoDev:
  97.         case cutDev:
  98.         case copyDev:
  99.         case pasteDev:
  100.         case clearDev:
  101.         case updateDev:
  102.             break;
  103.         case macDev:
  104.             rv = do_check(dp);
  105.             break;
  106.         case initDev:
  107.             rv = do_init(dp, numItems);
  108.             break;
  109.         case closeDev:
  110.             do_close((cdev_data_hdl)val);
  111.             break;
  112.         case hitDev:
  113.             do_hit((cdev_data_hdl)val, dp, item + numItems, evntp, numItems);
  114.             break;
  115.     }
  116.     return(rv);
  117. }
  118.  
  119. Boolean is_system7(void)
  120. {
  121.     Boolean    f;
  122.     OSErr    err;
  123.     long    r;
  124.     
  125.     if(f = TrapAvailable(_Gestalt)) {
  126.         err = Gestalt(gestaltSystemVersion, &r);
  127.         if(err != noErr)    f = false;
  128.         else if(r <0x0700) f = false;
  129.         else f = true;
  130.     }
  131.     return(f);
  132. }
  133.  
  134. Handle Get1Resource_in_system_heap(OSType rType, short id)
  135. {
  136.     THz        oldZone;
  137.     Handle    h;
  138.     
  139.     oldZone = GetZone();
  140.     SetZone(SystemZone());
  141.     h = Get1Resource(rType, id);
  142.     SetZone(oldZone);
  143.     return(h);
  144. }
  145.  
  146. //    gestalt check routines -------------------------
  147.  
  148. #define TrapMask 0x0800
  149.  
  150. short NumToolboxTraps( void )
  151. {
  152.     if (NGetTrapAddress(_InitGraf, ToolTrap) ==
  153.             NGetTrapAddress(0xAA6E, ToolTrap))
  154.         return(0x0200);
  155.     else
  156.         return(0x0400);
  157. }
  158.  
  159. TrapType GetTrapType(short theTrap)
  160. {
  161.  
  162.     if ((theTrap & TrapMask) > 0)
  163.         return(ToolTrap);
  164.     else
  165.         return(OSTrap);
  166.  
  167. }
  168.  
  169. Boolean TrapAvailable(short theTrap)
  170. {
  171.  
  172.     TrapType    tType;
  173.  
  174.     tType = GetTrapType(theTrap);
  175.     if (tType == ToolTrap)
  176.     theTrap = theTrap & 0x07FF;
  177.     if (theTrap >= NumToolboxTraps())
  178.         theTrap = _Unimplemented;
  179.  
  180.     return (NGetTrapAddress(theTrap, tType) !=
  181.             NGetTrapAddress(_Unimplemented, ToolTrap));
  182. }
  183.  
  184. //    event routines ---------------------------------
  185.  
  186.     //    open and close routines ------------------------
  187.  
  188. long do_check(DialogPtr dp)
  189. {
  190.     Handle    h;
  191.     long    is_ok = 0;
  192.     
  193.     SetPort(dp);
  194.     if( TrapAvailable(_Gestalt) ) {
  195.         if( is_system7() ) {
  196.             is_ok = 1;
  197.                 //    When you receive macDev message, you should check
  198.                 //    your control panel can run. If it can, return 1.
  199.                 //    If cannot, return 0.
  200.         }
  201.     }
  202.     else
  203.         Alert(RSRC_NUMBER_BASE + NO_7_RSRC, nil);
  204.     
  205.     return(is_ok);
  206. }
  207.  
  208. long do_init(DialogPtr dp, short numItems)
  209. {
  210.     cdev_data_hdl    ch;
  211.     init_data_hdl    ih;
  212.     Handle            h;
  213.     
  214.     SetPort(dp);
  215.     ih = load_setting();
  216.     if(!ih)        Alert(RSRC_NUMBER_BASE + ALERT_RSRC, nil);
  217.     ch = (cdev_data_hdl)NewHandle(sizeof(cdev_data));
  218.     (**ch).temp_init_data = **ih;
  219.     DisposeHandle((Handle)ih);
  220.     setup_ditems(ch , dp, numItems);
  221.     return((long)ch);
  222. }
  223.  
  224. init_data_hdl load_setting(void)
  225. {
  226.     init_data_hdl        h = nil, sysheap_data_hdl = nil;
  227.     old_init_data_hdl    old_h = nil;
  228.     short                save_ref_num;
  229.     prefs_file            pf;
  230.     int                    er;
  231.     OSErr                err;
  232.     long                address;
  233.  
  234.     err = Gestalt(CREATOR, &address);
  235.     
  236.     if(err == NO_ERROR) {
  237.         h = (init_data_hdl)NewHandle(sizeof(init_data));
  238.         sysheap_data_hdl = (init_data_hdl)address;
  239.         **h = **sysheap_data_hdl;
  240.     }
  241.     else {
  242.         save_ref_num = CurResFile();
  243.         er = open_prefs_file(&pf);
  244.         if(er != CAUTION_ERROR) {
  245.             if(er == NO_ERROR) {
  246.                 h = (init_data_hdl)Get1Resource_in_system_heap(SETTING_RSRC, RSRC_NUMBER_BASE + 1);
  247.                 if(h) {
  248.                     HNoPurge((Handle)h);
  249.                     DetachResource((Handle)h);
  250.                 }
  251.                 else {
  252.                     old_h = (old_init_data_hdl)Get1Resource(SETTING_RSRC, RSRC_NUMBER_BASE);
  253.                     if(old_h) {
  254.                         h = (init_data_hdl)NewHandleSys(sizeof(init_data));
  255.                         if(h) {
  256.                             (**h).drag_on        = (**(init_data_hdl)old_h).drag_on;
  257.                             (**h).grow_on        = (**(init_data_hdl)old_h).grow_on;
  258.                             (**h).push_on        = (**(init_data_hdl)old_h).push_on;
  259.                             (**h).pop_on        = (**(init_data_hdl)old_h).pop_on;
  260.                             (**h).push_sound    = (**(init_data_hdl)old_h).push_sound;
  261.                             (**h).pop_sound        = (**(init_data_hdl)old_h).pop_sound;
  262.                             (**h).push_key[0]    = (**(init_data_hdl)old_h).push_key[0];
  263.                             (**h).push_key[1]    = (**(init_data_hdl)old_h).push_key[1];
  264.                             (**h).push_key[2]    = (**(init_data_hdl)old_h).push_key[2];
  265.                             (**h).push_key[3]    = (**(init_data_hdl)old_h).push_key[3];
  266.                             (**h).pop_key[0]    = (**(init_data_hdl)old_h).pop_key[0];
  267.                             (**h).pop_key[1]    = (**(init_data_hdl)old_h).pop_key[1];
  268.                             (**h).pop_key[2]    = (**(init_data_hdl)old_h).pop_key[2];
  269.                             (**h).pop_key[3]    = (**(init_data_hdl)old_h).pop_key[3];
  270.                             (**h).show_init_icon= (**(init_data_hdl)old_h).show_init_icon;
  271.                             (**h).no_marquee    = false;
  272.                             (**h).drag_key[0]    = false;
  273.                             (**h).drag_key[1]    = false;
  274.                             (**h).drag_key[2]    = false;
  275.                             (**h).drag_key[3]    = true;
  276.                             ReleaseResource((Handle)old_h);
  277.                             save_setting(h, &pf);
  278.                         }
  279.                     }
  280.                 }
  281.                 CloseResFile(pf.RsrcRefNum);
  282.             }
  283.             else if(er == OPEN_ERROR) {
  284.                 h = (init_data_hdl)NewHandleSys(sizeof(init_data));
  285.                 if(h) {
  286.                     (**h).drag_on        = true;
  287.                     (**h).grow_on        = true;
  288.                     (**h).push_on        = true;
  289.                     (**h).pop_on        = true;
  290.                     (**h).push_sound    = true;
  291.                     (**h).pop_sound        = true;
  292.                     (**h).push_key[0]    = false;
  293.                     (**h).push_key[1]    = true;
  294.                     (**h).push_key[2]    = false;
  295.                     (**h).push_key[3]    = false;
  296.                     (**h).pop_key[0]    = true;
  297.                     (**h).pop_key[1]    = false;
  298.                     (**h).pop_key[2]    = false;
  299.                     (**h).pop_key[3]    = false;
  300.                     (**h).show_init_icon= true;
  301.                     (**h).no_marquee    = false;
  302.                     (**h).drag_key[0]    = false;
  303.                     (**h).drag_key[1]    = false;
  304.                     (**h).drag_key[2]    = false;
  305.                     (**h).drag_key[3]    = true;
  306.                     save_setting(h, &pf);
  307.                 }
  308.             }
  309.             UseResFile(save_ref_num);
  310.             Alert(RSRC_NUMBER_BASE + RESTART_RSRC, nil);
  311.         }
  312.         UseResFile(save_ref_num);
  313.     }
  314.     return(h);
  315. }
  316.  
  317. int open_prefs_file(prefs_file *pf)
  318. {
  319.     OSErr    er;
  320.     int        rn;
  321.     
  322.     er = FindFolder(kOnSystemDisk, kPreferencesFolderType, kDontCreateFolder,
  323.                         &(pf->vRefNum), &(pf->DirID));
  324.     if(er == 0) {
  325.         rn = HOpenResFile(pf->vRefNum, pf->DirID, PREFS_TITLE, fsRdWrPerm);
  326.         if(rn != -1) {
  327.             pf->RsrcRefNum = rn;
  328.             return(NO_ERROR);
  329.         }
  330.         return(OPEN_ERROR);
  331.     }
  332.     return(CAUTION_ERROR);
  333. }
  334.  
  335. void save_setting(init_data_hdl sysheap_data_hdl, prefs_file *pf_ptr)
  336. {
  337.     Handle            h;
  338.     init_data_hdl    work_data_hdl;
  339.     FInfo            f_info;
  340.     
  341.     HCreateResFile(pf_ptr->vRefNum, pf_ptr->DirID, PREFS_TITLE);
  342.     f_info.fdType = 'pref';
  343.     f_info.fdCreator = CREATOR;
  344.     f_info.fdFlags = 0;
  345.     HSetFInfo(pf_ptr->vRefNum, pf_ptr->DirID, PREFS_TITLE, &f_info);
  346.         //    You must call 'open_prefs_file' again.
  347.         //    Because HSetFInfo closes a file.
  348.     open_prefs_file(pf_ptr);
  349.  
  350.     work_data_hdl = (init_data_hdl)NewHandle(sizeof(init_data));
  351.     if(work_data_hdl) {
  352.         **work_data_hdl = **sysheap_data_hdl;
  353.         if(h = Get1Resource(SETTING_RSRC, RSRC_NUMBER_BASE + 1))
  354.             RmveResource(h);
  355.         AddResource((Handle)work_data_hdl, SETTING_RSRC, RSRC_NUMBER_BASE + 1, "\p");
  356.         ReleaseResource((Handle)work_data_hdl);
  357.         CloseResFile(CurResFile());
  358.     }
  359. }
  360.  
  361. void do_close(cdev_data_hdl ch)
  362. {
  363.     prefs_file    pf;
  364.     
  365.     open_prefs_file(&pf);
  366.     if(    ((**ch).temp_init_data.push_on == true) &&
  367.         ((**ch).temp_init_data.pop_on  == true) &&
  368.         (key1[0] == key2[0])    &&
  369.         (key1[1] == key2[1])    &&
  370.         (key1[2] == key2[2])    &&
  371.         (key1[3] == key2[3])    ) {
  372.             Alert(RSRC_NUMBER_BASE + SAME_RSRC, nil);
  373.             (**ch).temp_init_data.pop_on = false;
  374.     }
  375.     apply_setting(ch);
  376.     save_setting((init_data_hdl)ch, &pf);
  377.     DisposeHandle((Handle)ch);
  378. }
  379.  
  380.     //    other event routines ---------------------------
  381.  
  382. void do_hit(cdev_data_hdl ch, DialogPtr dp, short hit_item,
  383.                 EventRecord *evntp, short numItems)
  384. {
  385.     switch(hit_item) {
  386.         case k_drag_on:
  387.             (**ch).temp_init_data.drag_on = !(**ch).temp_init_data.drag_on;
  388.             setup_ditems(ch, dp, numItems);
  389.             apply_setting(ch);
  390.             break;
  391.         case k_grow_on:
  392.             (**ch).temp_init_data.grow_on = !(**ch).temp_init_data.grow_on;
  393.             setup_ditems(ch, dp, numItems);
  394.             apply_setting(ch);
  395.             break;
  396.         case k_push_on:
  397.             (**ch).temp_init_data.push_on = !(**ch).temp_init_data.push_on;
  398.             setup_ditems(ch, dp, numItems);
  399.             apply_setting(ch);
  400.             break;
  401.         case k_pop_on:
  402.             (**ch).temp_init_data.pop_on = !(**ch).temp_init_data.pop_on;
  403.             setup_ditems(ch, dp, numItems);
  404.             apply_setting(ch);
  405.             break;
  406.         case k_push_sound:
  407.             (**ch).temp_init_data.push_sound = !(**ch).temp_init_data.push_sound;
  408.             setup_ditems(ch, dp, numItems);
  409.             apply_setting(ch);
  410.             break;
  411.         case k_pop_sound:
  412.             (**ch).temp_init_data.pop_sound = !(**ch).temp_init_data.pop_sound;
  413.             setup_ditems(ch, dp, numItems);
  414.             apply_setting(ch);
  415.             break;
  416.         case k_show_icon:
  417.             (**ch).temp_init_data.show_init_icon = !(**ch).temp_init_data.show_init_icon;
  418.             setup_ditems(ch, dp, numItems);
  419.             apply_setting(ch);
  420.             break;
  421.         case k_push_ctrl:
  422.         case k_push_shift:
  423.         case k_push_option:
  424.         case k_push_command:
  425.             key1[hit_item - k_push_ctrl] = !key1[hit_item - k_push_ctrl];
  426.             check_key_combination(ch, hit_item - k_push_ctrl);
  427.             setup_ditems(ch, dp, numItems);
  428.             apply_setting(ch);
  429.             break;
  430.         case k_pop_ctrl:
  431.         case k_pop_shift:
  432.         case k_pop_option:
  433.         case k_pop_command:
  434.             key2[hit_item - k_pop_ctrl] = !key2[hit_item - k_pop_ctrl];
  435.             check_key_combination(ch, hit_item - k_pop_ctrl);
  436.             setup_ditems(ch, dp, numItems);
  437.             apply_setting(ch);
  438.             break;
  439.         case b_push_ctrl:
  440.         case b_push_shift:
  441.         case b_push_option:
  442.         case b_push_command:
  443.             key1[hit_item - b_push_ctrl] = !key1[hit_item - b_push_ctrl];
  444.             check_key_combination(ch, hit_item - b_push_ctrl);
  445.             setup_ditems(ch, dp, numItems);
  446.             apply_setting(ch);
  447.             break;
  448.         case b_pop_ctrl:
  449.         case b_pop_shift:
  450.         case b_pop_option:
  451.         case b_pop_command:
  452.             key2[hit_item - b_pop_ctrl] = !key2[hit_item - b_pop_ctrl];
  453.             check_key_combination(ch, hit_item - b_pop_ctrl);
  454.             setup_ditems(ch, dp, numItems);
  455.             apply_setting(ch);
  456.             break;
  457.         case k_no_marquee:
  458.             (**ch).temp_init_data.no_marquee = !(**ch).temp_init_data.no_marquee;
  459.             setup_ditems(ch, dp, numItems);
  460.             apply_setting(ch);
  461.             break;
  462.         case k_drag_ctrl:
  463.         case k_drag_shift:
  464.         case k_drag_option:
  465.         case k_drag_command:
  466.             key3[hit_item - k_drag_ctrl] = !key3[hit_item - k_drag_ctrl];
  467.             check_key_combination(ch, hit_item - k_drag_ctrl);
  468.             setup_ditems(ch, dp, numItems);
  469.             apply_setting(ch);
  470.             break;
  471.         case b_drag_ctrl:
  472.         case b_drag_shift:
  473.         case b_drag_option:
  474.         case b_drag_command:
  475.             key3[hit_item - b_drag_ctrl] = !key3[hit_item - b_drag_ctrl];
  476.             check_key_combination(ch, hit_item - b_drag_ctrl);
  477.             setup_ditems(ch, dp, numItems);
  478.             apply_setting(ch);
  479.             break;
  480.         case k_about:
  481.             about(RSRC_NUMBER_BASE + ABOUT_RSRC, nil);
  482.             break;
  483.     }
  484. }
  485.  
  486. void apply_setting(cdev_data_hdl cur_data_hdl)
  487. {
  488.     init_data_hdl    sysheap_data_hdl;
  489.     OSErr            err;
  490.     long            address;
  491.     
  492.     
  493.     err = Gestalt(CREATOR, &address);
  494.     if(err == NO_ERROR) {
  495.         sysheap_data_hdl = (init_data_hdl)address;
  496.         **sysheap_data_hdl = (**cur_data_hdl).temp_init_data;
  497.     }
  498. }
  499.  
  500. void setup_ditems(cdev_data_hdl ch, DialogPtr dp, short numItems)
  501. {
  502.     hilite_btn(ch, dp, numItems);
  503.  
  504.     set_check_btn(dp, k_drag_on        + numItems,  (**ch).temp_init_data.drag_on);
  505.     set_check_btn(dp, k_grow_on        + numItems,  (**ch).temp_init_data.grow_on);
  506.     set_check_btn(dp, k_push_on        + numItems,  (**ch).temp_init_data.push_on);
  507.     set_check_btn(dp, k_pop_on        + numItems,  (**ch).temp_init_data.pop_on);
  508.     set_check_btn(dp, k_push_sound    + numItems,  (**ch).temp_init_data.push_sound);
  509.     set_check_btn(dp, k_pop_sound    + numItems,  (**ch).temp_init_data.pop_sound);
  510.     set_check_btn(dp, k_push_ctrl    + numItems,  key1[0]);
  511.     set_check_btn(dp, k_push_shift    + numItems,  key1[1]);
  512.     set_check_btn(dp, k_push_option    + numItems,  key1[2]);
  513.     set_check_btn(dp, k_push_command+ numItems,  key1[3]);
  514.     set_check_btn(dp, k_pop_ctrl    + numItems,  key2[0]);
  515.     set_check_btn(dp, k_pop_shift    + numItems,  key2[1]);
  516.     set_check_btn(dp, k_pop_option    + numItems,  key2[2]);
  517.     set_check_btn(dp, k_pop_command    + numItems,  key2[3]);
  518.     set_check_btn(dp, k_show_icon    + numItems,  (**ch).temp_init_data.show_init_icon);
  519.     set_check_btn(dp, k_no_marquee    + numItems,  (**ch).temp_init_data.no_marquee);
  520.     set_check_btn(dp, k_drag_ctrl    + numItems,  key3[0]);
  521.     set_check_btn(dp, k_drag_shift    + numItems,  key3[1]);
  522.     set_check_btn(dp, k_drag_option    + numItems,  key3[2]);
  523.     set_check_btn(dp, k_drag_command+ numItems,  key3[3]);
  524.         //    These are not clever :-)
  525. }
  526.  
  527. void hilite_btn(cdev_data_hdl ch, DialogPtr dp, short numItems)
  528. {
  529.     short    item_type;
  530.     Handle    h;
  531.     Rect    r;
  532.     int        i, button;
  533.     
  534.     button = k_push_sound;
  535.     for( i = 0; i <= 4; i++) {
  536.         GetDItem(dp, numItems + button + i, &item_type, &h, &r);
  537.         HiliteControl((ControlHandle)h, (!(**ch).temp_init_data.push_on) * 255);
  538.     }
  539.     button = k_pop_sound;
  540.     for( i = 0; i <= 4; i++) {
  541.         GetDItem(dp, numItems + button + i, &item_type, &h, &r);
  542.         HiliteControl((ControlHandle)h, (!(**ch).temp_init_data.pop_on) * 255);
  543.     }
  544.     button = k_drag_ctrl;
  545.     for( i = 0; i <= 3; i++) {
  546.         GetDItem(dp, numItems + button + i, &item_type, &h, &r);
  547.         HiliteControl((ControlHandle)h,
  548.             (!( (**ch).temp_init_data.no_marquee * (**ch).temp_init_data.drag_on) ) * 255);
  549.     }
  550.     GetDItem(dp, numItems + k_no_marquee, &item_type, &h, &r);
  551.     HiliteControl((ControlHandle)h, (!(**ch).temp_init_data.drag_on) * 255);
  552.  
  553. void set_check_btn(DialogPtr dp, short item_num, Boolean is_on)
  554. {
  555.     short    item_type;
  556.     Handle    h;
  557.     Rect    r;
  558.     
  559.     GetDItem(dp, item_num, &item_type, &h, &r);
  560.     if(is_on)    SetCtlValue((ControlHandle)h, 1);
  561.     else        SetCtlValue((ControlHandle)h, 0);
  562. }
  563.  
  564. void check_key_combination(cdev_data_hdl ch, short key_num)
  565. {
  566.     if(    (key1[0] == false)    &&
  567.         (key1[1] == false)    &&
  568.         (key1[2] == false)    &&
  569.         (key1[3] == false)    ) {
  570.             key1[key_num] = true;
  571.     }
  572.     if(    (key2[0] == false)    &&
  573.         (key2[1] == false)    &&
  574.         (key2[2] == false)    &&
  575.         (key2[3] == false)    ) {
  576.             key2[key_num] = true;
  577.     }
  578. }
  579.  
  580.  
  581. void about(short id, void *p)
  582. {
  583.     GrafPtr            saved_port;
  584.     PenState        saved_pen_state;
  585.     WindowPtr        wp;
  586.     EventRecord        an_event;
  587.     KeyMap            my_keymap;
  588.     PicHandle        title_hdl;
  589.     Handle            icon_hdl;
  590.     Rect            r;
  591.     Str255            str;
  592.     int                i;
  593.     long            ticks, num_of_str;
  594.     short            fh, fv;
  595.     Pattern            gray_pat;
  596.     Boolean            exit_draw = false, color_icon, color_qd;
  597.     RGBColor        fore_color, back_color;
  598.     
  599.     gray_pat[0]= 0x55;
  600.     for(i = 1; i <8; i++) gray_pat[i] = ~gray_pat[i-1];
  601.  
  602.         //    I use GetNewCWindow, not GetDialog. Because StaticText of a dialog
  603.         //    displays 12pt of geneva, but I want to display text with 9pt.
  604.         //    If you don't want to use other than 12pt, use GetDialog. Fonts can be
  605.         //    changed with SetDAFont ( New Inside Macintosh: SetDialogFont ).
  606.     GetPort(&saved_port);
  607.     GetPenState(&saved_pen_state);
  608.     if(color_qd = TrapAvailable(_GetForeColor)) {
  609.         GetForeColor(&fore_color);
  610.         GetBackColor(&back_color);
  611.     }
  612.     SetRect(&r, 5, 5, 148, 35);
  613.     wp = GetNewCWindow(id, 0, (WindowPtr)-1);
  614.     ShowWindow(wp);
  615.     SetPort(wp);
  616.     title_hdl = GetPicture(RSRC_NUMBER_BASE);
  617.     DrawPicture(title_hdl, &r);
  618.     PenNormal();
  619.     TextSize(9);
  620.     GetIndString(str, RSRC_NUMBER_BASE + 1, 1);
  621.     StringToNum(str, &num_of_str);
  622.     for(i = 0; i <= num_of_str; i++) {
  623.         GetIndString(str, RSRC_NUMBER_BASE, i + 1);
  624.         MoveTo(20, 45 + i * 12);
  625.         DrawString(str); 
  626.     }
  627.     SetRect(&r, 280, 0, 328, 48);
  628.     color_icon = TrapAvailable(_GetCIcon);
  629.     if(color_icon) {
  630.         icon_hdl = (Handle)GetCIcon(RSRC_NUMBER_BASE + WINDOW_ICON);
  631.         PlotCIcon(&r, (CIconHandle)icon_hdl);
  632.     }
  633.     else {
  634.         icon_hdl = GetIcon(RSRC_NUMBER_BASE + WINDOW_ICON);
  635.         PlotIcon(&r, icon_hdl);
  636.     }
  637.     SetRect(&r, 1, 0, 49, 48);
  638.     PenPat(gray_pat);
  639.     PenMode(patXor);
  640.     FrameRect(&r);
  641.     while(!exit_draw) {
  642.         FrameRect(&r);
  643.         OffsetRect(&r, 2, 0);
  644.         FrameRect(&r);
  645.         if(r.left == (280 - 47)) {
  646.             exit_draw = true;
  647.             if(color_icon)
  648.                 PlotCIcon(&r, (CIconHandle)icon_hdl);
  649.             else
  650.                 PlotIcon(&r, icon_hdl);
  651.         }
  652.     }
  653.     while(!(WaitNextEvent(mDownMask, &an_event, 100, 0)));
  654.     GetKeys(my_keymap);
  655.     if( (BitTst(my_keymap, COMMAND_KEY)) && (BitTst(my_keymap, OPTION_KEY))) {
  656.         EraseRect(&r);
  657.         OffsetRect(&r, 47, 0);
  658.         if(color_icon)
  659.             PlotCIcon(&r, (CIconHandle)icon_hdl);
  660.         else
  661.             PlotIcon(&r, icon_hdl);
  662.         OffsetRect(&r, 0, 48);
  663.         if(color_icon)
  664.             PlotCIcon(&r, (CIconHandle)icon_hdl);
  665.         else
  666.             PlotIcon(&r, icon_hdl);
  667.         SysBeep(1);
  668.         while(!(WaitNextEvent(mDownMask, &an_event, 100, 0)));
  669.     }
  670.     if(color_icon)
  671.         DisposeCIcon((CIconHandle)icon_hdl);
  672.     else
  673.         DisposeHandle(icon_hdl);
  674.     DisposeWindow(wp);
  675.     SetPort(saved_port);
  676.     SetPenState(&saved_pen_state);
  677.     if(color_qd) {
  678.         RGBForeColor(&fore_color);
  679.         RGBBackColor(&back_color);
  680.     }
  681.     FlushEvents(everyEvent, 0);
  682. }
  683.